package com.example.invoke.controller;

import com.example.invoke.entity.User;
import com.example.invoke.entity.UserRepo;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(value = "cache")
public class CacheController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserRepo userRepo;

    private Cache<String, Object> redisCache = CacheBuilder.newBuilder()
            .initialCapacity(2)
            .concurrencyLevel(1)
            .expireAfterWrite(1, TimeUnit.MINUTES)
            .recordStats()
            .removalListener(notification -> {
                System.out.println(notification.getKey() + "__" + notification);
            })
            .build(new CacheLoader<String, Object>() {
                @Override
                public Object load(String key) throws Exception {
                    return getFrom(key);
                }
            });


    private Object getFrom(String key) {
        String[] split = key.split(":");
        if (split.length == 2) {
            Long userId = Long.valueOf(split[1]);
            boolean existsById = userRepo.existsById(userId);
            if (!existsById) {
                String res = "autoKey" + new Random().nextInt();
                User user = new User();
                user.setName(res);
                userRepo.save(user);
                return res;
            }
            User one = userRepo.getOne(userId);
            return one.getName();
        }
        return null;
    }

    private String KEY = "USER:";

    @GetMapping(value = "get")
    public Object getCache (String userId) throws ExecutionException {
        String key = KEY + userId;
        return redisCache.get(key, () -> getFrom(key));
//        Object ifPresent = redisCache.getIfPresent(key);
//        System.out.println(ifPresent);
//        return ifPresent;
    }

    @GetMapping(value = "status")
    public String status () throws ExecutionException {
        CacheStats stats = redisCache.stats();
        System.out.println(stats);
        return stats.toString();
    }
}
